﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SchemaMonitor.json
{
    public abstract class CSoft
    {
        //Members
        private readonly CNodeBasic _root;
        protected readonly CUser _cache;

        //Constructor
        protected CSoft(CNodeBasic root, CUser cache)
        {
            _root = root;
            _cache = cache;
        }

		//Internal
		public CNodeRoot Root_ { get { return (CNodeRoot)_root; } }
		public CNodeBasic Root { get { return _root; } }
		public CFieldList Fields { get { return _root.Fields; } }

		//Common
		public string Id { get { return GetStr("id"); } }
		public DateTime CreatedTime
		{
			get
			{
				return GetDate("created_time");
			}
		}
		public DateTime UpdatedTime
		{
			get
			{
				return GetDate("updated_time");
			}
		}
		public string StatusType
		{
			get
			{
				return GetStr("status_type");
			}
		}



		//Helpers)
		protected string PrivacyString
		{
			get
			{
				if (!Fields.Has("privacy"))
					return string.Empty;
				var f = Fields["privacy"].AsComposite;
				return f.GetString("value");
			}
		}
		protected CSoftCommentList GetComments(string key = "comments")
		{
			if (!Fields.Has(key))
				return new CSoftCommentList(0);
			var list = Get(key, null).AsPointerList(_cache.All);
			var comments = new CSoftCommentList(list.Count);
			foreach (var i in list)
				comments.Add(new CSoftComment(i.Root, _cache));
			return comments;
		}
		protected List<long> GetListLong(string key)
		{
			if (!Fields.Has(key))
				return new List<long>(0);
			return Get(key, null).AsLongList;
		}
		protected CSoftUser GetUser(string key, CUser user)
		{
			if (!Fields.Has(key))
				return null;
			var root = Fields[key].AsComposite;
			return null == root ? null : new CSoftUser(root, user) ;
		}
		protected string GetStr(string key)
        {
			var f = Get(key, null);
			if (null == f)
				return string.Empty;
			return f.AsString;
        }
        protected bool GetBool(string key)
        {
            return Get(key, false).AsBool;
		}
		protected int GetInt(string key)
		{
			return Get(key, int.MinValue).AsInteger;
		}
		protected long? GetLong(string key)
		{
			var f = Get(key, null);
			if (null == f)
				return null;
			return f.AsLong;
		}

		protected DateTime GetDate(string key)
		{
			var s = GetStr(key);
			return SchemaMonitor.html.CHtml.ToDate(s);
		}

		protected void SetBool(string key, bool value)
        {
            Get(key, false).AsBool = value;
        }

        //Private
        private CField Get(string key, object value)
        {
            var f = _root.Fields[key];
            if (null == f)
            {
				if (null == value)
					return null;

                f = CField.Factory(key, value, _root, _cache);

                _root.Fields.Add(f);
            }
            return f;
        }
    }
}
